package Offer29;

import java.util.ArrayList;

/**
 * @author 23737
 * @time 2021.9.24
 * 顺时针打印矩阵：
 * 输入一个矩阵，按照从外向里以顺时针的顺序依次打印出每一个数字。
 */
public class Test {
    public static void main(String[] args) {
        int[][] ints = new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        int[] ints1 = new Solution().spiralOrder(ints);
        for (int i = 0; i < ints1.length; i++) {
            System.out.print(ints1[i]+" ");
        }
    }
}

/*自己用链表加以实现，效率较低。模拟矩阵路径，层层输出来解题*/
class Solution {
    public int[] spiralOrder(int[][] matrix) {
        if (matrix.length == 0 || matrix[0].length == 0) {
            return new int[0];
        }
        //使用一个链表来进行存储
        ArrayList<Integer> arrayList = new ArrayList<>();
        //首先定位矩阵边界四个点
        int r1 = 0, r2 = matrix.length - 1, c1 = 0, c2 = matrix[0].length - 1;
        while (r1 <= r2 && c1 <= c2) {
            //存储最上边的一层
            for (int i = c1; i <= c2; i++) {
                arrayList.add(matrix[r1][i]);
            }
            //存储最右边的一层
            for (int i = r1 + 1; i <= r2; i++) {
                arrayList.add(matrix[i][c2]);
            }
            //存储最下边的一层
            if (r1 != r2) {
                for (int i = c2 - 1; i >= c1; i--) {
                    arrayList.add(matrix[r2][i]);
                }
            }
            //存储最左边的一层
            if (c1 != c2) {
                //这里尤其需要注意，不能有i>=r1，不然会把上一层的左上角的值多打印一次！！
                for (int i = r2 - 1; i > r1; i--) {
                    arrayList.add(matrix[i][c1]);
                }
            }
            r1++;
            r2--;
            c1++;
            c2--;
        }
        Object[] objects = arrayList.toArray();
        //使用一个数组来作为返回值
        int[] ints = new int[objects.length];
        for (int i = 0; i < objects.length; i++) {
            ints[i] = (int) objects[i];
        }
        return ints;
    }
}

/*官方题解*/
class SolutionTwo {
    public int[] spiralOrder(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return new int[0];
        }
        int rows = matrix.length, columns = matrix[0].length;
        int[] order = new int[rows * columns];
        int index = 0;
        int left = 0, right = columns - 1, top = 0, bottom = rows - 1;
        while (left <= right && top <= bottom) {
            for (int column = left; column <= right; column++) {
                order[index++] = matrix[top][column];
            }
            for (int row = top + 1; row <= bottom; row++) {
                order[index++] = matrix[row][right];
            }
            if (left < right && top < bottom) {
                for (int column = right - 1; column > left; column--) {
                    order[index++] = matrix[bottom][column];
                }
                for (int row = bottom; row > top; row--) {
                    order[index++] = matrix[row][left];
                }
            }
            left++;
            right--;
            top++;
            bottom--;
        }
        return order;
    }
}


